#!/usr/bin/env python
"""
"""
import xml.etree.ElementTree as ET
import sys
import os
import shutil

def searchFile(path, wordf, wordfp, res):
    """
    find xml files
    """
    for f in os.listdir(path):
        fp = os.path.join(path, f)
        if os.path.isfile(fp) and wordf in f:
            if wordfp in fp:
                res.append(fp)
        elif os.path.isdir(fp):
            searchFile(fp, wordf, wordfp, res)

def gatherInterfaceFile(module, fp, name):
    """
    copy int3erface.java to workspace
    """
    d = 'dubbo' + module
    if not os.path.exists(d):
        os.makedirs(d)
    if os.path.isfile(fp):
        shutil.copy(fp, d)
        return d + name
    return

def handleInterfaceFileAnnoteDel(filepath):
    """
    del annotes
    """
    sInit = 0
    sSlash = 1
    sBlockAnnote = 2
    sBlockAnnoteDot = 3
    sLineAnnote = 4
    sStr = 5
    sStrEscape = 6

    resfile = 'res.java'
    if os.path.isfile(resfile):
        os.remove(resfile)
    fpsrc = open(filepath)
    fpdst = open(resfile, 'w')
    
    state = sInit
    for line in fpsrc.readlines():
        line = line.replace('**/', '*/')
        
        for c in line:
            if state == sInit:
                if c == '/':
                    state = sSlash
                elif c == '"':
                    state = sStr
                    fpdst.write(c)
                else:
                    fpdst.write(c)
            elif state == sSlash:
                if c == '*':
                    state = sBlockAnnote
                elif c == '/':
                    state = sLineAnnote
                else:
                    fpdst.write('/')
                    fpdst.write(c)
            elif state == sBlockAnnote:
                if c == '*':
                    state = sBlockAnnoteDot
                #if c == "/":
                #    state = sInit
            elif state == sBlockAnnoteDot:
                if c == '/':
                    state = sInit
                else:
                    state = sBlockAnnote
            elif state == sLineAnnote:
                if c == '\n':
                    state = sInit
            elif state == sStr:
                if c == '\\':
                    state = sStrEscape
                    fpdst.write(c)
                elif c == '"':
                    state = sInit
                    fpdst.write(c)
                else:
                    fpdst.write(c)
            elif state == sStrEscape:
                state = sStr
                fpdst.write(c)
    fpsrc.close()
    fpdst.close()
    os.remove(filepath)
    shutil.copyfile(resfile, filepath)

def handleInterfaceFileLine2One(filepath):
    """
    line to one
    """
    lineContent = ""
    resfile = 'res.java'
    if os.path.isfile(resfile):
        os.remove(resfile)
    fpsrc = open(filepath)
    fpdst = open(resfile, 'w')
    
    for line in fpsrc.readlines():
        info = line.strip()
        if info == '':
            fpdst.write(line)
            continue
        if info.startswith('@') or info.endswith('}') or info.endswith('{'):
            fpdst.write(line)
        elif info.endswith(';') and lineContent == '':
            fpdst.write(line)
        else:
            if info.endswith(';'):
                lineContent += line.strip()
                fpdst.write(lineContent + '\n')
                lineContent = "" 
            else:
                if lineContent == '': 
                    lineContent += line.rstrip() + ' ' 
                else:
                    lineContent += line.strip() + ' '

    fpsrc.close()
    fpdst.close()
    os.remove(filepath)
    shutil.copyfile(resfile, filepath)

def handleInterfaceFileFormat(filepath):
    """
    fileformat: dos to linux
    """
    with open(filepath,'rb+') as fobj:
        data = fobj.read()
        data = data.replace('\r\n', '\n')
        fobj.seek(0, 0)
        fobj.truncate()
        fobj.write(data)

def collectInterface():
    """
    collect interfaces from provider.xml
    """
    providerxmls = []
    searchFile('./', 'provider.xml', 'main/resources/', providerxmls)
    for f in providerxmls:
        module = f.split('src')[0]
        module = module.replace('-', '_')
        tree = ET.parse(f)
        root = tree.getroot()
        for child in root:
            cattr = child.attrib
            if cattr.has_key('interface') & cattr.has_key('ref'):
                ref = cattr['ref']
                interface = cattr['interface']
                interfaceName = interface[interface.rindex('.')+1:]
                res = []
                searchFile('./', interfaceName+'.java', interface.replace('.', '/'), res)
                fp = gatherInterfaceFile(module[1:], res[0], interfaceName + '.java')

                if fp:
                    handleInterfaceFileAnnoteDel(fp)   
                    handleInterfaceFileLine2One(fp)
                    handleInterfaceFileFormat(fp)

                value = {'ref': ref, 'module': module, 'interface': interface}
                map.update({interfaceName:value})
                
def makeBeanFileExe(xmlf):
    """
    make dubbo.xml
    """
    module = xmlf.split('src')[0][1:]
    module = module.replace('-', '_')
    d = 'bean' + module
    fn = d + 'dubbo.xml'
    if not os.path.exists(d):
        os.makedirs(d)
    if os.path.isfile(fn):
        os.remove(fn)

    f = open(fn, 'a+')
    f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
    f.writelines(['<beans xmlns="http://www.springframework.org/schema/beans" \n', 
                 '\txmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n',
                 '\txmlns:context="http://www.springframework.org/schema/context"\n',
                 '\txmlns:tx="http://www.springframework.org/schema/tx"\n',
                 '\txmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"\n',
                 '\txmlns:util="http://www.springframework.org/schema/util"\n',
                 '\txmlns:mvc="http://www.springframework.org/schema/mvc"\n',
                 '\txsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\n',
                 '\thttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd\n',
                 '\thttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd\n',
                 '\thttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd\n',
                 '\thttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"\n',
                 '\tdefault-autowire="byName">\n\n'])
    
    tree = ET.parse(xmlf)
    root = tree.getroot()
    for child in root:
        cattr = child.attrib
        if cattr.has_key('interface') & cattr.has_key('id'):
            interface = cattr['interface']
            interfaceName = interface[interface.rindex('.')+1:]
            mapdata = map.get(interfaceName)
            if not mapdata:
                print('%s  %s' %(module, interface))
            else:
                clazz = 'com.qunar.train.mock' + mapdata.get('module')[1:].replace('/', '.')  + interfaceName
                cont = '\t<bean id="' + cattr['id'] + '" class="' + clazz + '"/>\n'
                f.write(cont)

    f.write('\n</beans>') 
    f.close()
   
def makeBeanFile():
    """
    make beans for module from consumer.xml
    """
    consumerxmls = []
    searchFile('./', 'consumer.xml', 'main/resources/', consumerxmls)
    for f in consumerxmls:
        makeBeanFileExe(f)


if __name__ == "__main__":
    map = {}
    collectInterface()
    makeBeanFile()
   
    #handleInterfaceFileAnnoteDel('test.java') 
    #handleInterfaceFileLine2One("test.java")
    #handleInterfaceFileFormat('test.java')
    
